home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / gouraud1.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-10-28  |  9.6 KB  |  598 lines

  1. PROGRAM gouraud1;
  2. {
  3.     Gouraud shading or what?
  4.     - by Bjarke Viksφe
  5.     sep 1994
  6.     "Shade HLine from Color1 to Color2" routine by The Faker/S!P
  7.     Please remember to credit him for this if you use it for anything.
  8.     I'm sure he's put a lot of effort in to get things that fast and neat.
  9.  
  10.     And it does look pretty strange with the low resolution. I'll try
  11.     to make another version with 1 pixel resolution.
  12. }
  13.  
  14. {{$DEFINE DEBUG}
  15.  
  16. USES
  17.     DEMOINIT;
  18.  
  19. CONST
  20.     NUMBER_FACES = 6;
  21.     NUMBER_COORDS = 8;
  22.     BOX = 140; {size of box}
  23.  
  24. TYPE
  25.     SlopeType = array[0..200*2] of integer;
  26.  
  27.     FaceType = RECORD
  28.         l1,l2,l3,l4 : byte;
  29.     end;
  30.  
  31.  
  32. VAR
  33.     slope,zslope : SlopeType;
  34.     face : array[1..NUMBER_FACES] of FaceType;
  35.     cbuffer : array[0..NUMBER_COORDS*4-1] of integer;
  36.  
  37.     LineTable1 : array[0..319] of byte;
  38.     LineTable2 : array[0..319] of byte;
  39.  
  40.     miny,maxy, scrminy,scrmaxy : integer;
  41.     lastscrminy,lastscrmaxy : integer;
  42.  
  43.     sinustabel : array[0..639] of integer;
  44.     v1,v2,v3 : word;
  45.     cos1,sin1,cos2,sin2,cos3,sin3 : integer;
  46.  
  47.  
  48. CONST
  49.     display1 : word = $0000;
  50.     display2 : word = $4000;
  51.     {setup coords for a box}
  52.     coords : array[0..NUMBER_COORDS*3-1] of integer =
  53.         (box,box,-box, -box,box,-box, -box,-box,-box, box,-box,-box,
  54.         box,box,box, -box,box,box, -box,-box,box, box,-box,box);
  55.  
  56.  
  57. (*------------------------------------------------*)
  58.  
  59. procedure SetupSinus;
  60. var
  61.     i : integer;
  62.     v, vadd : real;
  63. begin
  64.     v:=0.0;
  65.     vadd:=(2.0*pi/512.0);
  66.     for i:=0 to 639 do begin
  67.         sinustabel[i]:=round(sin(v)*32767);
  68.         v:=v+vadd;
  69.     end;
  70. end;
  71.  
  72. procedure SetupFaces;
  73. {setup faces. Make sure face keeps track of which coordinates it uses!}
  74. begin
  75.     with face[1] do begin l1:=3; l2:=2; l3:=1; l4:=0; end;
  76.     with face[2] do begin l1:=4; l2:=5; l3:=6; l4:=7; end;
  77.     with face[3] do begin l1:=0; l2:=1; l3:=5; l4:=4; end;
  78.     with face[4] do begin l1:=1; l2:=2; l3:=6; l4:=5; end;
  79.     with face[5] do begin l1:=2; l2:=3; l3:=7; l4:=6; end;
  80.     with face[6] do begin l1:=3; l2:=0; l3:=4; l4:=7; end;
  81. end;
  82.  
  83. procedure InitDemo;
  84. var
  85.     i : integer;
  86. begin
  87.     Screen_Off;
  88.     ClearWholeScreen;
  89.     SetupSinus;
  90.     SetupFaces;
  91.  
  92.     scrminy := 0; scrmaxy := 200;
  93.     lastscrminy := 0; lastscrmaxy := 200;
  94.     v1:=0; v2:=0; v3:=0;
  95.  
  96.     for i:=1 to 63 do SetRGB(i,0,64-i,0);
  97.     for i:=64 to 255 do SetRGB(i,0,0,0);
  98.  
  99.     for i:=0 to 319 do begin
  100.         LineTable1[i]:=(15 SHL (i AND 3)) AND 15;
  101.         LineTable2[i]:=(2 SHL (i AND 3))-1;
  102.     end;
  103.  
  104.     Screen_On;
  105. end;
  106.  
  107.  
  108. (*------------------------------------------------*)
  109.  
  110. procedure SwapDisplay;
  111. var
  112.     temp : word;
  113. begin
  114.     temp:=display2;
  115.     display2:=display1;
  116.     display1:=temp;
  117.     SetAddress(Ptr(SEGA000,display2));
  118. end;
  119.  
  120. procedure ClearScreen(y1,y2 : integer); assembler;
  121. asm
  122.     mov    dx,$3C4
  123.     mov    ax,$0F02
  124.     out    dx,ax
  125.  
  126.     mov    bx,y1        {clear box around vector - only y-coords are actually}
  127.     mov    dx,y2        {used for calculation... x-coords are constant 192 pixels}
  128.     sub    dx,bx
  129.     cmp    dx,200
  130.     ja        @done
  131.  
  132.     lea    si,ytabel
  133.     add    bx,bx
  134.     mov    di,[si+bx]
  135.     add    di,display1
  136.     add    di,16
  137.  
  138.     mov    es,SEGA000
  139.     DB LONG; xor ax,ax
  140.     mov    bx,48/4
  141. @loop:
  142.     mov    cx,bx
  143.     rep; DB LONG; stosw
  144.     add    di,WIDTH-48
  145.     dec    dl
  146.     jnz    @loop
  147. @done:
  148. end;
  149.  
  150.  
  151. (*------------------------------------------------*)
  152.  
  153. procedure ClearSlope; assembler;
  154. asm
  155.     mov    ax,ds
  156.     mov    es,ax
  157.     lea    di,slope
  158.     DB LONG; mov ax,$8000; DW $8000;
  159.     cld
  160.     mov    cx,TYPE(slopetype)/4
  161.     rep; DB LONG; stosw
  162. end;
  163.  
  164. procedure CalcSlope(l1,l2 : integer); assembler;
  165. var
  166.     z1,z2,coladd : word;
  167.     xlowadd : word;
  168.     ysize : integer;
  169. asm
  170.     lea    si,cbuffer
  171.     DB LONG; xor cx,cx
  172.     mov    bx,l1                    {get first coords}
  173.     shl    bx,3
  174.     mov    ax,[si+bx+4]        {get z value}
  175.     shr    ax,2
  176.     mov    z2,ax
  177.     mov    dx,[si+bx]            {get x/y coords}
  178.     mov    cx,[si+bx+2]
  179.  
  180.     mov    ax,l2                    {get second coords}
  181.     shl    ax,3
  182.     add    si,ax
  183.     mov    ax,[si+4]            {get z value}
  184.     shr    ax,2
  185.     mov    z1,ax
  186.     mov    ax,[si]                {get x/y coords}
  187.     mov    bx,[si+2]
  188.  
  189.     cmp    bx,cx                    {make sure we go downwards...}
  190.     jle    @noswap
  191.     mov    si,z1                    {swap z}
  192.     xchg    z2,si
  193.     mov    z1,si
  194.     xchg    ax,dx                    {swap x}
  195.     xchg    bx,cx                    {sway y}
  196. @noswap:
  197.  
  198.     cmp    bx,miny                {record miny and maxy}
  199.     jae    @miny
  200.     mov    miny,bx
  201. @miny:
  202.     cmp    cx,maxy
  203.     jbe    @maxy
  204.     mov    maxy,cx
  205. @maxy:
  206.  
  207.     sub    cx,bx
  208.     jcxz    @zero
  209.     mov    ysize,cx
  210.     add    bx,bx
  211.     add    bx,bx
  212.     lea    si,slope
  213.     add    si,bx
  214.  
  215.     push    ax
  216.     sub    dx,ax
  217.     inc    dx
  218.  
  219.     mov    ax,dx
  220.     DB LONG; shl    ax,16
  221.     {cdq} DB $66,$99
  222.     DB LONG; idiv    cx
  223.     DB LONG; mov    dx,ax
  224.     DB LONG; shr    dx,16
  225.     mov    xlowadd,ax
  226.     {DX also loaded... but kept alive}
  227.  
  228.     push    dx                        {also calc z-slope}
  229.     mov    ah,BYTE PTR z2
  230.     sub    ah,BYTE PTR z1
  231.     xor    al,al
  232.     cwd
  233.     idiv    cx
  234.     mov    coladd,ax
  235.     pop    dx
  236. @one:
  237.     pop    cx
  238.  
  239.     xor    bx,bx
  240.     mov    ah,BYTE PTR z1    {prepare also z-slope calc. z1:=z1*256}
  241.     xor    al,al
  242.     mov    di,$8000
  243. @loop:
  244.     cmp    [si],di
  245.     jne    @other
  246.     mov    [si+TYPE(SlopeType)],ah
  247.     mov    [si],cx
  248.     add    si,4
  249.     add    bx,xlowadd
  250.     adc    cx,dx
  251.     add    ax,coladd
  252.     dec    ysize
  253.     jnz    @loop
  254.     jmp    NEAR PTR @zero
  255. @other:
  256.     mov    [si+TYPE(SlopeType)+2],ah
  257.     mov    [si+2],cx
  258.     add    si,4
  259.     add    bx,xlowadd
  260.     adc    cx,dx
  261.     add    ax,coladd
  262.     dec    ysize
  263.     jnz    @loop
  264. @zero:
  265. end;
  266.  
  267.  
  268. (*------------------------------------------------*)
  269.  
  270. procedure CalcAngle;
  271. begin
  272.     sin1:=sinustabel[v1]; cos1:=sinustabel[v1+128];
  273.     sin2:=sinustabel[v2]; cos2:=sinustabel[v2+128];
  274.     sin3:=sinustabel[v3]; cos3:=sinustabel[v3+128];
  275.     v1:=(v1+2) AND 511;
  276.     v2:=(v2-1) AND 511;
  277.     v3:=(v3+1) AND 511;
  278. end;
  279.  
  280. procedure RotateAllCoords; assembler;
  281. {Rotate all coords in "coords" around all 3 axis and make
  282.  perspective calcualtion. Store x,y,z results in "cbuffer"}
  283. var
  284.     xkoord,ykoord,zkoord, n : integer;
  285. asm
  286.     mov    ax,ds
  287.     mov    es,ax
  288.     lea    si,coords
  289.     lea    di,cbuffer
  290.     mov    n,NUMBER_COORDS
  291.     cld
  292. @loop:
  293.     lodsw
  294.     mov    xkoord,ax
  295.     lodsw
  296.     mov    ykoord,ax
  297.     lodsw
  298.     mov    zkoord,ax
  299.  
  300.     mov    ax,xkoord               {rotate around Z-axis}
  301.     push    ax
  302.     imul    Cos1
  303.     add    ax,ax
  304.     adc    dx,dx
  305.     mov    bx,dx
  306.     mov    ax,ykoord
  307.     imul    Sin1
  308.     add    ax,ax
  309.     adc    dx,dx
  310.     sub    bx,dx
  311.     mov    xkoord,bx
  312.     pop    ax
  313.     imul    Sin1
  314.     add    ax,ax
  315.     adc    dx,dx
  316.     mov    bx,dx
  317.     mov    ax,ykoord
  318.     imul    Cos1
  319.     add    ax,ax
  320.     adc    dx,dx
  321.     add    bx,dx
  322.     mov    ykoord,bx
  323.  
  324.     mov    ax,ykoord               {rotate around Y-axis}
  325.     push    ax
  326.     imul    Cos2
  327.     add    ax,ax
  328.     adc    dx,dx
  329.     mov    bx,dx
  330.     mov    ax,zkoord
  331.     imul    Sin2
  332.     add    ax,ax
  333.     adc    dx,dx
  334.     sub    bx,dx
  335.     mov    ykoord,bx
  336.     pop    ax
  337.     imul    Sin2
  338.     add    ax,ax
  339.     adc    dx,dx
  340.     mov    bx,dx
  341.     mov    ax,zkoord
  342.     imul    Cos2
  343.     add    ax,ax
  344.     adc    dx,dx
  345.     add    bx,dx
  346.     mov    zkoord,bx
  347.  
  348.     mov    ax,xkoord               {rotate around X-axis}
  349.     push    ax
  350.     imul    Cos3
  351.     add    ax,ax
  352.     adc    dx,dx
  353.     mov    bx,dx
  354.     mov    ax,zkoord
  355.     imul    Sin3
  356.     add    ax,ax
  357.     adc    dx,dx
  358.     sub   bx,dx
  359.     mov    xkoord,bx
  360.     pop    ax
  361.     imul    Sin3
  362.     add    ax,ax
  363.     adc    dx,dx
  364.     mov    bx,dx
  365.     mov    ax,zkoord
  366.     imul    Cos3
  367.     add    ax,ax
  368.     adc    dx,dx
  369.     add    bx,dx
  370.     mov    zkoord,bx
  371.  
  372.     add    bx,800
  373.     and    bx,bx
  374.     jnz    @zero
  375.     mov    bl,1
  376. @zero:
  377.  
  378.     mov    ax,xkoord
  379.     cwd
  380.     mov    dl,ah
  381.     mov    ah,al
  382.     xor    al,al
  383.     idiv    bx
  384.     add    ax,160
  385.     stosw
  386.  
  387.     mov    ax,ykoord
  388.     cwd
  389.     mov    dl,ah
  390.     mov    ah,al
  391.     xor    al,al
  392.     idiv    bx
  393.     add    ax,100
  394.     stosw
  395.  
  396.     mov    ax,bx
  397.     sub    ax,390
  398.     stosw
  399.     add    di,2
  400.  
  401.     dec    n
  402.     jnz    @loop
  403. end;
  404.  
  405.  
  406.  
  407. function FaceShown(l1,l2,l3 : byte) : boolean;
  408. var
  409.     a,b : longint;
  410. begin
  411.     a := longmul(cbuffer[l1]-cbuffer[l2],cbuffer[l3+1]-cbuffer[l2+1]);
  412.     b := longmul(cbuffer[l1+1]-cbuffer[l2+1],cbuffer[l3]-cbuffer[l2]);
  413.     FaceShown := (a-b) > 0;
  414. end;
  415.  
  416.  
  417. procedure FillShape(y,ysize : integer); assembler;
  418. var
  419.     c1,c2 : byte;
  420. asm
  421.     cmp    ysize,200
  422.     jae    @done
  423.     mov    ax,y
  424.     add    ax,ax
  425.     mov    si,ax
  426.     mov    di,[si+OFFSET ytabel]
  427.     add    di,display1
  428.     lea    si,slope
  429.     add    ax,ax
  430.     add    si,ax
  431.  
  432.     mov    es,SEGA000
  433.     mov    dx,$3C4
  434.     mov    al,$02
  435.     out    dx,al
  436.     cld
  437. @yloop:
  438.     mov    bh,[si+TYPE(slopetype)] {fetch z value}
  439.     lodsw                                    {fetch first xpos}
  440.     mov    dx,ax
  441.     mov    bl,[si+TYPE(slopetype)] {fetch second z value}
  442.     lodsw                                    {fetch second xpos}
  443.     cmp    ax,dx
  444.     jle    @exchange
  445.     xchg    ax,dx
  446.     xchg    bl,bh
  447. @exchange:
  448.     mov    c1,bl
  449.     mov    c2,bh
  450.  
  451.     cmp    dx,0
  452.     jl        @filledout_fast
  453.     cmp    ax,320
  454.     jge    @filledout_fast
  455.     cmp    ax,0
  456.     jge    @cut1
  457.     xor    ax,ax
  458. @cut1:
  459.     cmp    dx,319
  460.     jle    @cut2
  461.     mov    dx,319
  462. @cut2:
  463.     push    si
  464.     push    di
  465.     mov    bx,ax
  466.     mov    si,dx
  467.     mov    dx,$3C5
  468.  
  469. {the next lines are ripped from THE FAKER/S!P shade example}
  470.     mov    al,[bx+OFFSET LineTable1]
  471.     mov    ah,[si+OFFSET LineTable2]
  472.     shr    bx,2
  473.     shr    si,2
  474.     mov    cx,si
  475.     sub    cx,bx
  476.     jcxz    @1
  477.     dec    cx
  478.     add    di,bx
  479.     mov    bh,ah
  480.     out    dx,al
  481.     mov    al,c1
  482.     shr    al,1
  483.     stosb
  484.     jcxz    @4
  485.     mov    al,$0F
  486.     out    dx,al
  487.     push    bx
  488.     xor    dx,dx
  489.     xor    al,al
  490.     mov    ah,c2
  491.     sub    ah,c1
  492.     sbb    dx,0
  493.     idiv    cx
  494.     mov    si,ax
  495.  
  496.     mov    dh,c1
  497.     xor    dl,dl
  498.     shr    cx,1
  499.     jnc    @2
  500.     add    dx,si
  501.     mov    ax,dx
  502.     shr    ax,9
  503.     stosb
  504.     jcxz    @5
  505.  
  506. @2:
  507.     add    dx,si
  508.     mov    bx,dx
  509.     shr    bx,1
  510.     add    dx,si
  511.     mov    ax,dx
  512.     shr    ax,1
  513.     mov    al,bh
  514.     stosw
  515.     loop    @2
  516.  
  517. @5: pop    bx
  518.  
  519. @4:
  520.     mov al,bh
  521.     mov dx,3c5h
  522.     out dx,al
  523.     mov al,c2
  524.     shr al,1
  525.     stosb
  526.     jmp @3
  527.  
  528. @1:
  529.     add    di,bx
  530.     and    al,ah
  531.     out    dx,al
  532.     mov    al,c1
  533.     add    al,c2
  534.     rcr    al,1
  535.     shr    al,1
  536.     stosb
  537.  
  538. @3:
  539.  
  540. @filledout:
  541.     pop    di
  542.     pop    si
  543. @filledout_fast:
  544.     add    di,WIDTH
  545.     dec    ysize
  546.     jnz    @yloop
  547. @done:
  548. end;
  549.  
  550.  
  551. procedure RunOnce;
  552. var
  553.     i : integer;
  554. begin
  555.     SwapDisplay;
  556.     VBLANK;
  557. {$IFDEF DEBUG}
  558.     SetRGB(0,30,0,0);
  559. {$ENDIF}
  560.  
  561.     ClearScreen(lastscrminy,lastscrmaxy);
  562.  
  563.     lastscrminy := scrminy; lastscrmaxy := scrmaxy;
  564.     scrminy := 200; scrmaxy := 0;
  565.  
  566.     CalcAngle;
  567.     RotateAllCoords;
  568.  
  569.     for i:=1 to NUMBER_FACES do begin
  570.         with face[i] do if FaceShown(l1 SHL 2,l2 SHL 2,l3 SHL 2) then begin
  571.             ClearSlope;
  572.             miny := 200; maxy := 0;
  573.             CalcSlope(l1,l2);
  574.             CalcSlope(l2,l3);
  575.             CalcSlope(l3,l4);
  576.             CalcSlope(l4,l1);
  577.             FillShape(miny, maxy-miny);
  578.             if (miny < scrminy) then scrminy := miny;
  579.             if (maxy > scrmaxy) then scrmaxy := maxy;
  580.         end;
  581.     end;
  582.  
  583. {$IFDEF DEBUG}
  584.     SetRGB(0,0,0,0);
  585.     while KeyHit[26] do ; {Hit 'P' to pause}
  586. {$ENDIF}
  587. end;
  588.  
  589.  
  590. begin
  591.     OpenScreen;
  592.     InitDemo;
  593.     SetAllInterrupts;
  594.     repeat RunOnce until Key='e';
  595.     RestoreAllInterrupts;
  596.     CloseScreen;
  597. end.
  598.